﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
//using System.Threading.Tasks;
using System.Windows.Forms;
using ZhiMiJson;

namespace HostSwitch
{

    public partial class Form1 : Form
    {
        [DllImport("user32.dll", EntryPoint = "SendMessageA")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);

        [DllImport("user32 ")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        private int numoflines = 0;
        public Form1()
        {
            //Sunisoft.IrisSkin.SkinEngine skin = new Sunisoft.IrisSkin.SkinEngine();
            //skin.SkinFile = Application.StartupPath.Replace(@"\bin\Debug", "") + @"\skins\SteelBlue.ssk";
            ////skin.SkinFile = System.Environment.CurrentDirectory + "\\skins\\" + "Emerald.ssk";              
            //skin.Active = true;
            InitializeComponent();
            Application.EnableVisualStyles();

        }

        

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Text = "ZhiMi JSON 修改器 2.0.2(X"+ PlateFormRunMode.ToString() + ")---285984303@qq.com";

            List<FileInfo> files = new List<FileInfo>();
            string[] fs = System.IO.Directory.GetFiles(@"e:\", "*.json");//, SearchOption.AllDirectories
            foreach (string file in fs)
            {
                files.Add(new FileInfo(file));
            }
            List<FileInfo> filesOrderedDESC = files.OrderByDescending(p => p.CreationTime).ToList();
            //List<FileInfo> filesOrderedASC = files.OrderBy(p => p.LastWriteTime).ToList();
            foreach (var item in filesOrderedDESC)
            {
                //if(item.Name.Contains("hosts_"))
                //{
                //    ListItem li = new ListItem(item.FullName, item.Name);
                //    this.checkedListBox1.Items.Add(li);
                //}
                ListItem li = new ListItem(item.FullName, item.Name);
                this.checkedListBox1.Items.Add(li);

            }
            
        }

        /// <summary>
        /// 判断操作系统是32位还是64位
        /// </summary>
        virtual public int PlateFormRunMode
        {
            get
            {
                if (IntPtr.Size == 8)
                {
                    return 64;
                }
                return 32;

            }
        }

        private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.checkedListBox1.SelectedIndex >= 0)
                {
                    for (int i = 0; i < checkedListBox1.Items.Count; i++)
                    {
                        checkedListBox1.SetItemChecked(i, false);
                    }
                    var path = ((ListItem)this.checkedListBox1.SelectedItem).ID;
                    //MessageBox.Show(path);
                    // Open the stream and read it back.
                    using (FileStream fs = File.Open(path, FileMode.Open))
                    {
                        byte[] b = new byte[fs.Length];
                        UTF8Encoding temp = new UTF8Encoding(true);

                        while (fs.Read(b, 0, b.Length) > 0)
                        {
                            // Console.WriteLine(temp.GetString(b));
                            this.richTextBox1.Text = temp.GetString(b);
                        }
                        numoflines = richTextBox1.Lines.Length;
                        //toolStripStatusLabel1.Text = "此RTB共有" + numoflines.ToString() + "行";
                    }
                    this.checkedListBox1.SetItemChecked(this.checkedListBox1.SelectedIndex, true);
                    this.Text = "ZhiMi JSON 修改器 2.0.2(X" + PlateFormRunMode.ToString() + ")---"+ ((ListItem)this.checkedListBox1.SelectedItem).Name;

                }
            }
            catch (Exception err)
            {
                Trace.WriteLine(err.Message);
                
            }
            
        }
        
        private void btnOK_Click(object sender, EventArgs e)
        {
            if (this.checkedListBox1.SelectedIndex >= 0)
            {
                try
                {
                    string txtLineNum = this.txtLine.Text;
                    int LineNum = int.Parse(txtLineNum);

                    if (txtLineNum.Length < 1)
                    {
                        MessageBox.Show("请输入想开始的行");
                        return;
                    }
                    else if (int.Parse(txtLineNum) > numoflines)
                    {
                        MessageBox.Show("错误！你输入的行数大于文本框现有的行数");
                        return;
                    }

                    // Create a temporary file, and put some data into it.
                    //string path = Path.GetTempFileName();
                    var path = ((ListItem)this.checkedListBox1.SelectedItem).ID;
                    //var host = @"C:\Windows\System32\drivers\etc\hosts";
                    //using (FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None))
                    //{
                    //    Byte[] info = new UTF8Encoding(true).GetBytes(this.richTextBox1.Text);
                    //    // Add some information to the file.
                    //    fs.Write(info, 0, info.Length);
                    //}

                    //using (FileStream fs = File.Open(host, FileMode.Create, FileAccess.Write, FileShare.None))
                    //{
                    //    Byte[] info2 = new UTF8Encoding(true).GetBytes(this.richTextBox1.Text);
                    //    // Add some information to the file.
                    //    fs.Write(info2, 0, info2.Length);
                    //}

                    int i = 0;
                    int firstNum = 0;
                    FileStream fs1 = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    using (StreamReader sr = new StreamReader(fs1, System.Text.Encoding.UTF8))
                    {
                        while (sr.Peek() > -1)
                        {
                            i++;
                            if (i >= LineNum)
                            {
                                //Console.WriteLine("T:" + sr.ReadLine());
                                string str = sr.ReadLine();

                                //string strPatten = @"((\d+)([a-z]))\s+";
                                string strPatten = @"""q_(.+)""";
                                Regex rex = new Regex(strPatten);
                                MatchCollection matches = rex.Matches(str);
                                
                                if(matches.Count > 0)
                                {
                                    int firstNum2 = int.Parse(matches[0].Groups[1].Value);
                                    if (firstNum2 >= firstNum)
                                    {
                                        firstNum = firstNum2;
                                    }
                                    Trace.WriteLine("firstNum=" + firstNum);
                                }
                                 
                                //提取匹配项
                                foreach (Match match in matches)
                                {
                                    GroupCollection groups = match.Groups;
                                    Trace.Write(string.Format("{0} 共有 {1} 个分组：{2}\n\r" , match.Value, groups.Count, strPatten));

                                    //提取匹配项内的分组信息
                                    for (int ii = 0; ii < groups.Count; ii++)
                                    {
                                        int newid = 0;
                                        Trace.Write(string.Format("分组 {0} 为 {1}，位置为 {2}，长度为 {3}\n\r", ii, groups[ii].Value, groups[ii].Index, groups[ii].Length));
                                        if(int.TryParse(groups[1].Value, out newid))
                                        {
                                            string[] lines = this.richTextBox1.Lines;
                                            Trace.WriteLine("newid=" + newid);
                                            if(newid >= firstNum)
                                            {
                                                newid = int.Parse(groups[1].Value) + 1;
                                                str = str.Replace(groups[1].Value, newid.ToString());


                                                lines[i - 1] = str;
                                                this.richTextBox1.Lines = lines;
                                            }
                                            

                                        }
                                    }
                                }

                                Trace.WriteLine("Line " + i.ToString() +":"+ str);
                                //Trace.WriteLine("LineNum=:" + i.ToString());
                            }
                            else
                            {
                                sr.ReadLine();
                                //Console.WriteLine("F:" + sr.ReadLine());
                            }
                            
                        }
                    }
                    if (i != 0)
                    {
                        LineNum = i;
                        //Console.WriteLine("LineNum:" + LineNum);
                        Trace.WriteLine("json end is " + LineNum);
                    }

                    //RunCmd();

                    FrmMsg frm = new FrmMsg("当前hosts切换到"+ ((ListItem)this.checkedListBox1.SelectedItem).Name);
                    frm.Show();

                }
                catch
                {

                }


            }
        }

        private void RunCmd()
        {
            string str = "ipconfig /flushdns"; //ipconfig /displaydns    //显示DNS缓存内容

            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;    //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = true;//不显示程序窗口
            p.Start();//启动程序

            //向cmd窗口发送输入信息
            p.StandardInput.WriteLine(str + "&exit");

            p.StandardInput.AutoFlush = true;
            //p.StandardInput.WriteLine("exit");
            //向标准输入写入要执行的命令。这里使用&是批处理命令的符号，表示前面一个命令不管是否执行成功都执行后面(exit)命令，如果不执行exit命令，后面调用ReadToEnd()方法会假死
            //同类的符号还有&&和||前者表示必须前一个命令执行成功才会执行后面的命令，后者表示必须前一个命令执行失败才会执行后面的命令



            //获取cmd窗口的输出信息
            string output = p.StandardOutput.ReadToEnd();

            //StreamReader reader = p.StandardOutput;
            //string line=reader.ReadLine();
            //while (!reader.EndOfStream)
            //{
            //    str += line + "  ";
            //    line = reader.ReadLine();
            //}

            p.WaitForExit();//等待程序执行完退出进程
            p.Close();


            Console.WriteLine(output);
            Debug.WriteLine(output);
            //Trace.WriteLine(output);

        }

        private void checkedListBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int index = checkedListBox1.IndexFromPoint(e.X, e.Y);
            checkedListBox1.SelectedIndex = index;
            if (checkedListBox1.SelectedIndex != -1)
            {
                try
                {
                    // Create a temporary file, and put some data into it.
                    //string path = Path.GetTempFileName();
                    //var path = ((ListItem)this.checkedListBox1.SelectedItem).ID;
                    var host = @"C:\Windows\System32\drivers\etc\hosts";
                    //using (FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None))
                    //{
                    //    Byte[] info = new UTF8Encoding(true).GetBytes(this.textBox1.Text);
                    //    // Add some information to the file.
                    //    fs.Write(info, 0, info.Length);
                    //}

                    using (FileStream fs = File.Open(host, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        Byte[] info2 = new UTF8Encoding(true).GetBytes(this.richTextBox1.Text);
                        // Add some information to the file.
                        //fs.Write(info2, 0, info2.Length);
                    }

                    //RunCmd();

                    FrmMsg frm = new FrmMsg("当前hosts切换到" + ((ListItem)this.checkedListBox1.SelectedItem).Name);
                    frm.Show();
                }
                catch 
                {

                    
                }
                

            }
        }

        private void btn_FlushDNS_Click(object sender, EventArgs e)
        {
            //RunCmd();
            string json = this.richTextBox1.Text;
            if (JsonSplit.IsJson(json))//传入的json串
            {
                MessageBox.Show("json格式合法","",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("json格式不合法", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void lnk_OpenDir_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string path = @"C:\Windows\System32\drivers\etc\";
            System.Diagnostics.Process.Start("explorer.exe", path);
        }

        private void btnGo_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Focus();
            string txtLineNum = this.txtLine.Text;
            //this.textBox1.SelectionStart = int.Parse(txtLineNum);
            //this.richTextBox1.Select(int.Parse(txtLineNum),0);
            //this.richTextBox1.ScrollToCaret();

            if (txtLineNum.Length < 1)
            {
                MessageBox.Show("请输入想跳至的行");
            }
            else if (int.Parse(txtLineNum) > numoflines)
            {
                MessageBox.Show("错误！你输入的行数大于文本框现有的行数");
            }
            else
            {
                richTextBox1.SelectionStart = richTextBox1.GetFirstCharIndexFromLine(int.Parse(txtLineNum)-1);
                richTextBox1.SelectionLength = 0;
                richTextBox1.Focus();
                richTextBox1.ScrollToCaret();
            }

            int EM_LINEINDEX = 0xBB;
            int EM_LINEFROMCHAR = 0xC9;
            int EM_GETSEL = 0xB0;
            int EM_GETLINE = 0xC4;

            //通过API完成很简单的 
            //通过向文本框传递EM_LINEFROMCHAR消息可以得到光标所在的行数 
            int Row = (int)SendMessage(richTextBox1.Handle, EM_LINEFROMCHAR, -1, 0)+1;

            //通过向文本框传递EM_GETSEL消息可以得到编辑控件中一段选定内容的起点与终点字符的个数 
            //int s = (int)SendMessage(richTextBox1.Handle, EM_GETSEL, 0, 0);
            //通过向文本框传递EM_GETSEL消息可以得到每一行的第一个字符在全文中的字符序号 
            int li = (int)SendMessage(richTextBox1.Handle, EM_LINEINDEX, -1, 0);

            this.lblLineNum.Text = "当前行:" +Row.ToString() + " 共"+ numoflines.ToString()+"行";



        }

        private void richTextBox1_MouseUp(object sender, MouseEventArgs e)
        {
            int EM_LINEINDEX = 0xBB;
            int EM_LINEFROMCHAR = 0xC9;
            int EM_GETSEL = 0xB0;
            int EM_GETLINE = 0xC4;

            //通过API完成很简单的 
            //通过向文本框传递EM_LINEFROMCHAR消息可以得到光标所在的行数 
            int Row = (int)SendMessage(richTextBox1.Handle, EM_LINEFROMCHAR, -1, 0) + 1;

            //通过向文本框传递EM_GETSEL消息可以得到编辑控件中一段选定内容的起点与终点字符的个数 
            //int s = (int)SendMessage(richTextBox1.Handle, EM_GETSEL, 0, 0);
            //通过向文本框传递EM_GETSEL消息可以得到每一行的第一个字符在全文中的字符序号 
            int li = (int)SendMessage(richTextBox1.Handle, EM_LINEINDEX, -1, 0);

            this.lblLineNum.Text = "当前行:" + Row.ToString() + " 共" + numoflines.ToString() + "行";
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                var path = ((ListItem)this.checkedListBox1.SelectedItem).ID;
                using (FileStream fs = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    Byte[] info2 = new UTF8Encoding(true).GetBytes(this.richTextBox1.Text);
                    // Add some information to the file.
                    fs.Write(info2, 0, info2.Length);
                }
                FrmMsg frm = new FrmMsg("保存成功:" + path);
                frm.Show();
            }
            catch
            {
                
            }
            finally
            {

            }
            
        }

        private void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start(e.LinkText); // call default browser
        }

        private void btnFind_Click(object sender, EventArgs e)
        {
            FindRichTextBoxString(this.txtFind.Text);
            if (this.FindPostion > 0)
            {
                richTextBox1_MouseUp(sender,null);
            }
        }
        private int FindPostion = 0;
        public void FindRichTextBoxString(string FindString)
        {
            if (FindPostion >= richTextBox1.Text.Length)// 已查到文本底部
            {
                MessageBox.Show("已到文本底部 , 再次查找将从文本开始处查找 ", "提示", MessageBoxButtons.OK,MessageBoxIcon.Information);
                FindPostion = 0;
                return;
            }// 下边语句进行查找， 返回找到的位置，返回 -1， 表示未找到，参数 1是要找的字符串
             // 参数2是查找的开始位置， 参数3是查找的一些选项， 如大小写是否匹配， 查找方向等
            FindPostion = richTextBox1.Find(FindString, FindPostion, RichTextBoxFinds.MatchCase);
            if (FindPostion == -1)// 如果未找到
            {
                MessageBox.Show("已到文本底部 , 再次查找将从文本开始处查找 ", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                FindPostion = 0;// 下次查找的开始位置
            }
            else// 已找到
            {
                richTextBox1.Focus();// 主窗体成为注视窗口
                
                FindPostion += FindString.Length;
            }// 下次查找的开始位置在此次找到字符串之后
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            this.richTextBox1.Width = this.Width - 190;
            this.richTextBox1.Height = this.Height - 72;
        }
    }
}
